package com.bsoft.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 将HTTP地址转换为二维码并进行Base64加密的工具类
 */
public class QrCodeUtil {

    // 二维码尺寸
    private static final int QR_CODE_SIZE = 300;
    // 图片格式
    private static final String IMAGE_FORMAT = "PNG";

    /**
     * 将HTTP地址转换为二维码并进行Base64加密
     * @param httpUrl 需要转换的HTTP地址
     * @return 二维码的Base64编码字符串
     * @throws WriterException 二维码生成异常
     * @throws IOException IO异常
     */
    public static String httpToQrCodeBase64(String httpUrl) throws WriterException, IOException {
        // 1. 生成二维码图片
        BufferedImage qrImage = generateQrCodeImage(httpUrl);

        // 2. 将图片转换为字节数组
        byte[] imageBytes = imageToByteArray(qrImage);

        // 3. 对字节数组进行Base64加密
        return encodeBase64(imageBytes);
    }

    /**
     * 生成二维码图片对象
     */
    private static BufferedImage generateQrCodeImage(String httpUrl) throws WriterException {
        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 字符编码
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 纠错级别
        hints.put(EncodeHintType.MARGIN, 1); // 边距

        // 生成二维码矩阵
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(httpUrl, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, hints);

        // 创建图片并绘制二维码
        BufferedImage image = new BufferedImage(QR_CODE_SIZE, QR_CODE_SIZE, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = (Graphics2D) image.getGraphics();

        // 白色背景
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, QR_CODE_SIZE, QR_CODE_SIZE);

        // 黑色二维码图案
        graphics.setColor(Color.BLACK);
        for (int i = 0; i < QR_CODE_SIZE; i++) {
            for (int j = 0; j < QR_CODE_SIZE; j++) {
                if (bitMatrix.get(j, i)) {
                    graphics.fillRect(j, i, 1, 1);
                }
            }
        }

        graphics.dispose();
        return image;
    }

    /**
     * 将BufferedImage转换为字节数组
     */
    private static byte[] imageToByteArray(BufferedImage image) throws IOException {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            ImageIO.write(image, IMAGE_FORMAT, outputStream);
            return outputStream.toByteArray();
        }
    }

    /**
     * 对字节数组进行Base64编码
     */
    private static String encodeBase64(byte[] bytes) {
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(bytes);
    }

    // 测试方法
    public static void main(String[] args) {
        try {
            String httpUrl = "https://www.chinaebill.cn/eips-wxapp-service/H5FinanceDisplay/showInvoice?invoice_code=51060125&invoice_number=0116246427&check_code=da0168&app_id=Ke8XxUStK&security=0FC9C8E5587A14C0DE3356232D92982A";
            String base64QrCode = httpToQrCodeBase64(httpUrl);

            System.out.println("二维码Base64编码:");
            System.out.println(base64QrCode);

            // 输出的Base64字符串可直接用于HTML的img标签: <img src="data:image/png;base64," + base64QrCode + ">
        } catch (Exception e) {
            System.err.println("处理失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
